package main

import (
	"fmt"
	"log"

	"github.com/pgparser/pkg/parser"
)

func main() {
	fmt.Println("PostgreSQL Parser - 常量折叠优化示例")
	fmt.Println("=====================================")

	// 测试常量折叠优化的SQL语句
	testCases := []struct {
		name string
		sql  string
		desc string
	}{
		{
			name: "数学运算折叠",
			sql:  "SELECT 2 + 3 * 4, 10 - 5 + 1 FROM users;",
			desc: "将数学表达式计算为常量值",
		},
		{
			name: "字符串连接折叠",
			sql:  "SELECT CONCAT('Hello', ' ', 'World') AS greeting FROM users;",
			desc: "将字符串连接表达式合并为单个字符串",
		},
		{
			name: "比较运算折叠",
			sql:  "SELECT * FROM users WHERE 1 = 1;",
			desc: "简化比较表达式",
		},
		{
			name: "数值比较折叠",
			sql:  "SELECT * FROM users WHERE 5 + 3 > 6;",
			desc: "简化数值比较表达式",
		},
		{
			name: "复合表达式折叠",
			sql:  "SELECT (2 + 3) * (4 - 1) AS result FROM users;",
			desc: "优化复合数学表达式",
		},
		{
			name: "混合表达式",
			sql:  "SELECT (2 + 3) * (4 - 1), 'User: ' || 'John' || ' Doe' FROM users WHERE (10 > 5) AND (true OR false);",
			desc: "复杂的混合常量表达式优化",
		},
		{
			name: "条件表达式",
			sql:  "SELECT CASE WHEN 1 = 1 THEN 'true' ELSE 'false' END FROM users;",
			desc: "CASE表达式中的常量条件优化",
		},
	}

	for i, tc := range testCases {
		fmt.Printf("\n测试用例 %d: %s\n", i+1, tc.name)
		fmt.Printf("描述: %s\n", tc.desc)
		fmt.Printf("原始SQL: %s\n", tc.sql)
		fmt.Println("---")

		// 解析SQL为AST
		ast, err := parser.ParseSQLToAST(tc.sql)
		if err != nil {
			log.Printf("解析错误: %v", err)
			continue
		}

		// 显示原始AST结构
		fmt.Println("原始AST结构:")
		printASTStructure(ast, 0)

		// 执行常量折叠优化
		optimizer := parser.NewConstantFolder()
		optimizedAST := optimizeAST(optimizer, ast)

		// 显示优化后的AST结构
		fmt.Println("\n优化后AST结构:")
		printASTStructure(optimizedAST, 0)

		// 生成优化后的SQL（如果可能）
		generator := parser.NewSQLGenerator(false)
		if canGenerateSQL(optimizedAST) {
			optimizedSQL := generator.Generate(optimizedAST)
			fmt.Printf("\n优化后SQL: %s\n", optimizedSQL)
		} else {
			fmt.Println("\n优化后SQL: [包含布尔字面量，无法生成SQL]")
		}

		// 分析优化效果
		analyzeOptimization(ast, optimizedAST)
	}

	// 演示手动常量折叠
	fmt.Println("\n=== 手动常量折叠演示 ===")
	demonstrateManualConstantFolding()
}

// printASTStructure 递归打印AST结构
func printASTStructure(node parser.Node, depth int) {
	indent := ""
	for i := 0; i < depth; i++ {
		indent += "  "
	}

	switch n := node.(type) {
	case *parser.SelectStmt:
		fmt.Printf("%sSELECT语句\n", indent)
		if len(n.Targets) > 0 {
			fmt.Printf("%s  目标列表:\n", indent)
			for i, target := range n.Targets {
				fmt.Printf("%s    [%d] ", indent, i)
				printASTStructure(target, depth+3)
			}
		}
		if n.Where != nil {
			fmt.Printf("%s  WHERE条件:\n", indent)
			printASTStructure(n.Where, depth+2)
		}

	case *parser.BinaryExpr:
		fmt.Printf("二元表达式 (%s)\n", getBinaryOpString(n.Operator))
		fmt.Printf("%s  左操作数: ", indent)
		printASTStructure(n.Left, depth+1)
		fmt.Printf("%s  右操作数: ", indent)
		printASTStructure(n.Right, depth+1)

	case *parser.Literal:
		fmt.Printf("字面量: %v (%s)\n", n.Value, getLiteralTypeString(n.Type))

	case *parser.ColumnRef:
		if n.Table != "" {
			fmt.Printf("列引用: %s.%s\n", n.Table, n.Column)
		} else {
			fmt.Printf("列引用: %s\n", n.Column)
		}

	case *parser.FunctionCall:
		fmt.Printf("函数调用: %s\n", n.Name)
		if len(n.Args) > 0 {
			fmt.Printf("%s  参数:\n", indent)
			for i, arg := range n.Args {
				fmt.Printf("%s    [%d] ", indent, i)
				printASTStructure(arg, depth+3)
			}
		}

	default:
		fmt.Printf("%T\n", node)
	}
}

// getBinaryOpString 获取二元操作符的字符串表示
func getBinaryOpString(op parser.BinaryOp) string {
	switch op {
	case parser.PLUS:
		return "+"
	case parser.MINUS:
		return "-"
	case parser.MULTIPLY:
		return "*"
	case parser.DIVIDE:
		return "/"
	case parser.MODULO:
		return "%"
	case parser.EQ:
		return "="
	case parser.NE:
		return "<>"
	case parser.LT:
		return "<"
	case parser.LE:
		return "<="
	case parser.GT:
		return ">"
	case parser.GE:
		return ">="
	case parser.AND:
		return "AND"
	case parser.OR:
		return "OR"
	case parser.CONCAT:
		return "||"
	default:
		return "UNKNOWN"
	}
}

// getLiteralTypeString 获取字面量类型的字符串表示
func getLiteralTypeString(t parser.LiteralType) string {
	switch t {
	case parser.StringLiteral:
		return "字符串"
	case parser.IntegerLiteral:
		return "整数"
	case parser.FloatLiteral:
		return "浮点数"
	case parser.BooleanLiteral:
		return "布尔值"
	case parser.NullLiteral:
		return "NULL"
	default:
		return "未知"
	}
}

// analyzeOptimization 分析优化效果
func analyzeOptimization(original, optimized parser.Node) {
	originalComplexity := calculateComplexity(original)
	optimizedComplexity := calculateComplexity(optimized)

	fmt.Printf("\n优化分析:\n")
	fmt.Printf("  原始复杂度: %d\n", originalComplexity)
	fmt.Printf("  优化后复杂度: %d\n", optimizedComplexity)

	if optimizedComplexity < originalComplexity {
		reduction := float64(originalComplexity-optimizedComplexity) / float64(originalComplexity) * 100
		fmt.Printf("  ✓ 复杂度降低: %.1f%%\n", reduction)
	} else if optimizedComplexity == originalComplexity {
		fmt.Printf("  ℹ️  复杂度保持不变\n")
	} else {
		fmt.Printf("  ⚠️  复杂度增加\n")
	}
}

// calculateComplexity 计算AST的复杂度（节点数量）
func calculateComplexity(node parser.Node) int {
	if node == nil {
		return 0
	}

	complexity := 1 // 当前节点

	switch n := node.(type) {
	case *parser.SelectStmt:
		for _, target := range n.Targets {
			complexity += calculateComplexity(target)
		}
		if n.Where != nil {
			complexity += calculateComplexity(n.Where)
		}
		for _, expr := range n.GroupBy {
			complexity += calculateComplexity(expr)
		}
		if n.Having != nil {
			complexity += calculateComplexity(n.Having)
		}

	case *parser.BinaryExpr:
		complexity += calculateComplexity(n.Left)
		complexity += calculateComplexity(n.Right)

	case *parser.FunctionCall:
		for _, arg := range n.Args {
			complexity += calculateComplexity(arg)
		}

	// 其他节点类型的复杂度计算可以在这里添加
	}

	return complexity
}

// canGenerateSQL 检查AST是否可以生成SQL（不包含布尔字面量）
func canGenerateSQL(node parser.Node) bool {
	switch n := node.(type) {
	case *parser.SelectStmt:
		// 检查目标列表
		for _, target := range n.Targets {
			if !canExpressionGenerateSQL(target) {
				return false
			}
		}
		// 检查WHERE条件
		if n.Where != nil && !canExpressionGenerateSQL(n.Where) {
			return false
		}
		// 检查其他条件...
		return true
	default:
		return true
	}
}

// canExpressionGenerateSQL 检查表达式是否可以生成SQL
func canExpressionGenerateSQL(expr parser.Expression) bool {
	switch e := expr.(type) {
	case *parser.Literal:
		// 检查是否为布尔字面量
		if e.Type == parser.BooleanLiteral {
			return false
		}
		return true
	case *parser.BinaryExpr:
		return canExpressionGenerateSQL(e.Left) && canExpressionGenerateSQL(e.Right)
	case *parser.UnaryExpr:
		return canExpressionGenerateSQL(e.Operand)
	default:
		return true
	}
}

// optimizeAST 优化AST节点
func optimizeAST(optimizer *parser.ConstantFolder, node parser.Node) parser.Node {
	switch n := node.(type) {
	case *parser.SelectStmt:
		// 优化SELECT语句中的表达式
		optimizedStmt := &parser.SelectStmt{
			Targets:  make([]parser.Expression, len(n.Targets)),
			From:     n.From,
			Where:    n.Where,
			GroupBy:  make([]parser.Expression, len(n.GroupBy)),
			Having:   n.Having,
			OrderBy:  n.OrderBy,
			Limit:    n.Limit,
			Offset:   n.Offset,
			Distinct: n.Distinct,
		}

		// 优化目标列表
		for i, target := range n.Targets {
			optimizedStmt.Targets[i] = optimizer.FoldExpression(target)
		}

		// 优化WHERE条件
		if n.Where != nil {
			optimizedStmt.Where = optimizer.FoldExpression(n.Where)
		}

		// 优化GROUP BY表达式
		for i, expr := range n.GroupBy {
			optimizedStmt.GroupBy[i] = optimizer.FoldExpression(expr)
		}

		// 优化HAVING条件
		if n.Having != nil {
			optimizedStmt.Having = optimizer.FoldExpression(n.Having)
		}

		// 优化LIMIT和OFFSET
		if n.Limit != nil {
			optimizedStmt.Limit = optimizer.FoldExpression(n.Limit)
		}
		if n.Offset != nil {
			optimizedStmt.Offset = optimizer.FoldExpression(n.Offset)
		}

		return optimizedStmt

	case parser.Expression:
		// 直接优化表达式
		return optimizer.FoldExpression(n)

	default:
		// 其他类型的节点暂不优化
		return node
	}
}

// demonstrateManualConstantFolding 演示手动常量折叠
func demonstrateManualConstantFolding() {
	fmt.Println("手动构建包含常量表达式的AST...")

	// 构建表达式: 2 + 3 * 4
	expr := &parser.BinaryExpr{
		Left: &parser.Literal{Value: 2, Type: parser.IntegerLiteral},
		Operator: parser.PLUS,
		Right: &parser.BinaryExpr{
			Left:     &parser.Literal{Value: 3, Type: parser.IntegerLiteral},
			Operator: parser.MULTIPLY,
			Right:    &parser.Literal{Value: 4, Type: parser.IntegerLiteral},
		},
	}

	fmt.Println("\n原始表达式结构:")
	printASTStructure(expr, 0)

	// 手动执行常量折叠
	optimizer := parser.NewConstantFolder()
	optimizedExpr := optimizer.FoldExpression(expr)

	fmt.Println("\n折叠后表达式结构:")
	printASTStructure(optimizedExpr, 0)

	// 演示字符串连接折叠
	fmt.Println("\n=== 字符串连接折叠演示 ===")
	stringExpr := &parser.BinaryExpr{
		Left: &parser.BinaryExpr{
			Left:     &parser.Literal{Value: "Hello", Type: parser.StringLiteral},
			Operator: parser.CONCAT,
			Right:    &parser.Literal{Value: " ", Type: parser.StringLiteral},
		},
		Operator: parser.CONCAT,
		Right:    &parser.Literal{Value: "World", Type: parser.StringLiteral},
	}

	fmt.Println("原始字符串表达式:")
	printASTStructure(stringExpr, 0)

	optimizedStringExpr := optimizer.FoldExpression(stringExpr)
	fmt.Println("\n折叠后字符串表达式:")
	printASTStructure(optimizedStringExpr, 0)
}